#include "CxSystemBuilder.h"
#include <string>
#include <boost/typeof/typeof.hpp>

using namespace std;
using namespace DataRevPart;
using boost::mutex;
using cv::Mat;

bool                         CxSystemBuilder::s_isBuilded=false;
volatile size_t              CxSystemBuilder::s_sysRef=0;
vector<CxBranchThread*>      CxSystemBuilder::s_branchInst(4,NULL);
vector<CxRevThread*>         CxSystemBuilder::s_revInst(4,NULL);
vector<CxImgProcThread*>     CxSystemBuilder::s_imgprocInst(4,NULL);
vector<CxDBThread*>          CxSystemBuilder::s_dbInst(4,NULL);
boost::mutex                 CxSystemBuilder::s_mu;



CxSystemBuilder::_showFunc               CxSystemBuilder::sig_showFunc[4];
CxSystemBuilder::_showcountFunc          CxSystemBuilder::sig_showcountFunc[4];
CxSystemBuilder::_connectFunc            CxSystemBuilder::sig_dbconnectFunc[4];


CxSystemBuilder::CxSystemBuilder()
{
    ++s_sysRef;
    if(!s_isBuilded)
        BuildPart();
}

CxSystemBuilder::~CxSystemBuilder()
{
    if((--s_sysRef)==0)
        DestoryPart();
}

void    CxSystemBuilder::BuildPart()
{
    boost::mutex::scoped_lock lock(s_mu);

    int j=0;
    for(BOOST_AUTO(i,s_revInst.begin());i!=s_revInst.end();++i,++j)
    {
        *i=new CxRevThread(j);
        (*i)->Start();
    }
    j=0;
    for(BOOST_AUTO(i,s_imgprocInst.begin());i!=s_imgprocInst.end();++i,++j)
    {
        IplImage *pBack=cvLoadImage("E:\\Files\\backg.jpg");
        *i=new CxImgProcThread(pBack,boost::bind(boost::ref(sig_showFunc[j]),_1),boost::bind(boost::ref(sig_showcountFunc[j]),_1,_2));
    }


    j=0;
    for(BOOST_AUTO(i,s_dbInst.begin());i!=s_dbInst.end();++i,++j)
        *i=new CxDBThread(j,boost::bind(boost::ref(sig_dbconnectFunc[j]),_1));


    j=0;
    for(BOOST_AUTO(i,s_branchInst.begin());i!=s_branchInst.end();++i,++j)
    {
        *i=new CxBranchThread(&s_revInst[j]->GetBuffer(),&s_imgprocInst[j]->GetBuffer(),&s_dbInst[j]->GetBuffer(),j);
        (*i)->Start();
    }
    s_isBuilded=true;
}


void    CxSystemBuilder::DestoryPart()
{
    boost::mutex::scoped_lock lock(s_mu);

//    for(BOOST_AUTO(i,s_branchInst.begin());i!=s_branchInst.end();++i)
//        delete *i;

//    for(BOOST_AUTO(i,s_revInst.begin());i!=s_revInst.end();++i)
//        delete *i;

//    for(BOOST_AUTO(i,s_dbInst.begin());i!=s_dbInst.end();++i)
//        delete *i;
//    for(BOOST_AUTO(i,s_imgprocInst.begin());i!=s_imgprocInst.end();++i)
//        delete *i;


    s_isBuilded=false;
}

 bool        CxSystemBuilder::OpenPort(size_t n,const std::string &portname,size_t  portno,CxRevThread::_ConnectFunc _func)
 {
     if(!s_isBuilded)
         return false;
     if(n>4)return false;

     boost::mutex::scoped_lock lock(s_mu);
     return s_revInst[n]->OpenPort(portname,portno,_func);
 }




